{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-12-02T14:51:30.422923Z",
     "start_time": "2024-12-02T14:51:01.214122Z"
    }
   },
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torchvision import datasets, transforms\n",
    "from torch.utils.data import DataLoader"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T14:51:37.225665Z",
     "start_time": "2024-12-02T14:51:37.167441Z"
    }
   },
   "cell_type": "code",
   "source": [
    "data_dir=\"C:/Users/Lenovo/Desktop/深度/实验三数据集/车辆分类数据集\"\n",
    "transform = transforms.Compose([\n",
    "    transforms.Resize((64, 64)),\n",
    "    transforms.ToTensor(),\n",
    "    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n",
    "])\n",
    "\n",
    "dataset = datasets.ImageFolder(data_dir, transform=transform)\n",
    "\n",
    "dataloader = DataLoader(dataset, batch_size=32, shuffle=True,num_workers=4)\n"
   ],
   "id": "ebd65cef0ed281d9",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T15:03:01.732548Z",
     "start_time": "2024-12-02T15:03:01.722150Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class ResidualBlock(nn.Module):\n",
    "    def __init__(self, in_channels, out_channels, Stride=1):\n",
    "        super(ResidualBlock, self).__init__()\n",
    "        self.shortcut = nn.Sequential()\n",
    "        self.bn = nn.BatchNorm2d(128)\n",
    "        if Stride!=1 or in_channels != out_channels:\n",
    "            self.shortcut = nn.Sequential(\n",
    "                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=Stride, bias=False),\n",
    "                nn.BatchNorm2d(out_channels)\n",
    "            )\n",
    " \n",
    "    def forward(self, x):\n",
    "        out = self.shortcut(x)\n",
    "        out = self.bn(out)\n",
    "        out = F.relu(out)\n",
    "        return out"
   ],
   "id": "5386d01621c343c2",
   "outputs": [],
   "execution_count": 29
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T15:15:52.007960Z",
     "start_time": "2024-12-02T15:15:51.992725Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)\n",
    "        self.bn1 = nn.BatchNorm2d(64)\n",
    "        self.conv2 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1)\n",
    "        self.bn2 = nn.BatchNorm2d(64)\n",
    "        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1)\n",
    "        self.bn3 = nn.BatchNorm2d(128)\n",
    "        self.conv4 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1)\n",
    "        self.bn4 = nn.BatchNorm2d(128)\n",
    "        self.conv5 = nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1)\n",
    "        self.bn5 = nn.BatchNorm2d(128)\n",
    "        self.fc = nn.Linear(128, 3)\n",
    "        self.jump1 = ResidualBlock(64, 128, Stride=2)\n",
    "        self.relu = nn.ReLU()\n",
    "        \n",
    "        \n",
    "    def forward(self, x):\n",
    "        out = F.relu(self.bn1(self.conv1(x)))\n",
    "        mem=out\n",
    "        out = self.relu(self.bn2(self.conv2(out)))\n",
    "        out = self.relu(self.bn3(self.conv3(out)))\n",
    "        out = self.relu(self.bn4(self.conv4(out)))\n",
    "        mem =self.jump1(mem)\n",
    "        #print(mem.shape)\n",
    "        out = self.relu(self.bn5(self.conv5(out)))+mem\n",
    "        #print(out.shape)\n",
    "        out=F.avg_pool2d(out,32)\n",
    "        #print(out.shape)\n",
    "        #out.squeeze()\n",
    "        out = out.view(out.size(0), -1)\n",
    "        #print(out.shape)\n",
    "        out = F.relu(self.fc(out))\n",
    "        return out\n",
    "        "
   ],
   "id": "a6f4676c7da973aa",
   "outputs": [],
   "execution_count": 63
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T15:15:52.678096Z",
     "start_time": "2024-12-02T15:15:52.643288Z"
    }
   },
   "cell_type": "code",
   "source": [
    "net = Net()\n",
    "criterion= nn.CrossEntropyLoss()\n",
    "optimizer= torch.optim.Adam(net.parameters(),lr=0.01)"
   ],
   "id": "aa1b9d679a05e0d4",
   "outputs": [],
   "execution_count": 64
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T15:15:53.279619Z",
     "start_time": "2024-12-02T15:15:53.263374Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def train_net(net,dataloader):\n",
    "    net.train()\n",
    "    train_batches=len(dataloader)\n",
    "    \n",
    "    for epoch in range(10):\n",
    "        total_loss=0\n",
    "        correct=0\n",
    "        sample_num=0\n",
    "        for batch_idx, (data, target) in enumerate(dataloader):            \n",
    "            optimizer.zero_grad()\n",
    "            output=net(data)\n",
    "            loss=criterion(output,target)\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            \n",
    "            #print(\"Batch %d, Loss: %.4f\"%(batch_idx,loss.item()))\n",
    "            \n",
    "            total_loss+=loss.item()\n",
    "            prediction=torch.argmax(output,1)\n",
    "            correct += (prediction==target).sum().item()\n",
    "            sample_num+=len(prediction)\n",
    "            \n",
    "        \n",
    "        loss=total_loss/train_batches\n",
    "        acc=correct/train_batches\n",
    "        print('Loss: {:.4f} Acc: {:.4f}'.format(loss,acc))\n",
    "    return loss,acc"
   ],
   "id": "d1e658afa56069e1",
   "outputs": [],
   "execution_count": 65
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-02T15:26:05.302261Z",
     "start_time": "2024-12-02T15:15:53.975996Z"
    }
   },
   "cell_type": "code",
   "source": "train_net(net,dataloader)",
   "id": "e8bfff191e9c7a9f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loss: 0.6429 Acc: 22.6977\n",
      "Loss: 0.5486 Acc: 25.4419\n",
      "Loss: 0.5441 Acc: 25.3953\n",
      "Loss: 0.4930 Acc: 26.1163\n",
      "Loss: 0.5048 Acc: 25.9070\n",
      "Loss: 0.5069 Acc: 25.5814\n",
      "Loss: 0.4828 Acc: 25.9535\n",
      "Loss: 0.4415 Acc: 26.8372\n",
      "Loss: 0.4175 Acc: 27.0465\n",
      "Loss: 0.4083 Acc: 27.1628\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(0.40831183278283406, 27.162790697674417)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 66
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "7b37e060c6fbf83c"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
